package com.yc.springmvc.core;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.yc.springmvc.core.annotation.RequestParam;
import com.yc.springmvc.core.util.StringUtil;

public class HandlerRequest {

	public static Object[] handle(HttpServletRequest req, Method method, HttpServletResponse resp) throws InstantiationException, IllegalAccessException {
		int count = method.getParameterCount();  // 获取这个方法的形参个数
		if (count <= 0) {
			return null;
		}
		
		Object[] args = new Object[count];  // 用来存放这个方法的形参值
		
		// 获取形参列表
		Parameter[] params = method.getParameters(); // 获取方法的形参列表
		
		String paramName = null;
		Class<?> cls = null;
		RequestParam requestParam = null;
		String value = null;
		int index = 0;
		Map<String, String[]> paramValues = null;
		Map<String, Object> paramMap = null;
		Field[] fields = null;
		String attrName = null;
		Class<?> attrType = null;
		Object obj = null;
		
		for (Parameter param : params) {  // 循环形参列表， 根据姓名名称和类型从请求中获取参数
			paramName = param.getName();
			cls = param.getType();  // 获取形参类型
			
			// 这个形参上有没有@RequestParam注解
			requestParam = param.getAnnotation(RequestParam.class);
			if (requestParam != null) {
				paramName = requestParam.value();  // 根据这个名称从请求中获取参数
			}
			
			value = req.getParameter(paramName);  // 根据形参名称从请求中获取参数
			if (cls == Integer.TYPE) {
				args[index] = Integer.parseInt(value);
			} else if (cls == Integer.class) {
				args[index] = Integer.valueOf(value);
			} else if (cls == Long.TYPE) {
				args[index] = Long.parseLong(value);
			} else if (cls == Long.class) {
				args[index] = Long.valueOf(value);
			} else if (cls == Double.TYPE) {
				args[index] = Double.parseDouble(value);
			} else if (cls == Double.class) {
				args[index] = Double.valueOf(value);
			} else if (cls == String.class) {
				args[index] = value;
			} else if (cls == Map.class){
				paramValues = req.getParameterMap();
				paramMap = new HashMap<String, Object>();
				for (Entry<String, String[]> entry : paramValues.entrySet()) {
					paramMap.put(entry.getKey(), entry.getValue()[0]);
				}
				args[index] = paramMap;
			} else if (ServletRequest.class == cls || cls == HttpServletRequest.class) {
				args[index] = req;
			} else if (ServletResponse.class == cls || cls == HttpServletResponse.class) {
				args[index] = resp;
			} else if (cls == HttpSession.class) {
				args[index] = req.getSession();
			} else if (cls == ServletContext.class) {
				args[index] = req.getServletContext();
			} else {  // 当成对象处理
				fields = cls.getDeclaredFields();
				obj = cls.newInstance();  // 实例化一个这个类的对象
				
				for (Field fd : fields) {  // 循环这个类的所有属性 注值
					fd.setAccessible(true);
					
					attrName = fd.getName();
					attrType = fd.getType();
					
					value = req.getParameter(attrName);  // 通过属性名从请求中取值
					if (StringUtil.checkNull(value)) {
						continue;
					}
					
					if (attrType == Integer.TYPE) {
						fd.set(obj, Integer.parseInt(value));
					} else if (attrType == Integer.class) {
						fd.set(obj, Integer.valueOf(value));
					} else if (attrType == Long.TYPE) {
						fd.set(obj, Long.parseLong(value));
					} else if (attrType == Integer.class) {
						fd.set(obj, Long.valueOf(value));
					} else if (attrType == Double.TYPE) {
						fd.set(obj, Double.parseDouble(value));
					} else if (attrType == Double.class) {
						fd.set(obj, Double.valueOf(value));
					} else {
						fd.set(obj, value);
					}
				}
				args[index] = obj;
			}
			++ index;
		}
		return args;
	}
	
}
